﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using wrsm.common.exceptions;
using wrsm.common.net;
using wrsm.battlenet.entity;
using wrsm.battlenet.exceptions;
using HtmlAgilityPack;

namespace wrsm.battlenet {

    /// <summary>
    /// Used to grab the current status of realms
    /// </summary>
    [CLSCompliant(true)]
    public class RealmStatusGrabber {

        /// <summary>
        /// Used to make web requests
        /// </summary>
        private WebRequest _webRequest = new WebRequest();

        /// <summary>
        /// Extracts information from HTML node, and packs it into a realm status entity
        /// </summary>
        /// <param name="realmNode">html node, from within battle.net document</param>
        /// <returns>Realm Status Entity</returns>
        private RealmStatus ExtractRealmInfo(HtmlNode realmNode) {
            RealmStatus realmStatus = new RealmStatus();
            realmStatus.Status
                = realmNode.SelectSingleNode("./td[@class='status']").Attributes["data-raw"].Value.Trim() == "down" ? false : true;
            realmStatus.Name
                = realmNode.SelectSingleNode("./td[@class='name']").InnerText.Trim();
            realmStatus.Type
                = realmNode.SelectSingleNode("./td[@class='type']").Attributes["data-raw"].Value.Trim();
            realmStatus.Population
                = realmNode.SelectSingleNode("./td[@class='population']").Attributes["data-raw"].Value.Trim();
            realmStatus.Locale
                = realmNode.SelectSingleNode("./td[@class='locale']").InnerText.Trim();
            return realmStatus;
        }

        /// <summary>
        /// Pull most up to date statuses for all realms on battle.net
        /// </summary>
        /// <returns>an array of up to date realm statuses</returns>
        public RealmStatus[] GetStatus() {
            try {
                var rawStatus = _webRequest.GetHttp((ConfigurationManager.AppSettings["wrsm.battlenet.url.realmstatus"]));
                HtmlDocument statusDocument = new HtmlDocument();
                statusDocument.LoadHtml(rawStatus);

                List<RealmStatus> realmStatus = new List<RealmStatus>();
                var nodes = statusDocument.DocumentNode.SelectNodes(ConfigurationManager.AppSettings["wrsm.battlenet.xpath.realmstatus"]);

                foreach (var realmNode in nodes) {
                    realmStatus.Add(ExtractRealmInfo(realmNode));
                }

                return realmStatus.ToArray();
            } catch (WrsmNetworkException caught) {
                throw new BattleNetApplicationException("Unable to get realm updates from battle.net", caught);
            }
        }

    }
}
